/*
 * Copyright (C) 2012 Rothens
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package rpg;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JPanel;
import rpg.gfx.Screen;

/**
 * rothens.tumblr.com
 * @author Rothens
 */
public class RPG extends Canvas implements Runnable {

    private boolean running;
    private int FPS = 0;
    private BufferedImage img;
    private Screen screen;
    private int[] pixels;
    private Game game;
    static int WIDTH = 640;
    static int HEIGHT = 480;
    public static final String version = "0.0.8";
    public static RPG rpg;
    public static KeyboardListener listener = new KeyboardListener();
    private Thread thread;
    private static File file1;
    public static JPanel panel;

    public RPG(File file1) {
        panel = new JPanel();

        this.file1 = file1;
        Dimension size = new Dimension(630, 470); //I dunno why is there a 10px width gap, but this will do it :D
        setSize(size);
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setPreferredSize(size);
        setFocusable(false);

        game = new Game(file1);

        screen = new Screen(WIDTH, HEIGHT);
        img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
        //rpg = new RPG(file1);
        panel.add(this);
        panel.setVisible(true);

    }

    public static void main(String[] args) {
        /*rpg = new RPG();
        
        
        //JFrame frame = new JFrame("Rothens RPG " + version);
        //Editor.game = new JPanel();
        //frame.setLayout(new GridLayout());
        
        //Editor.game.add(rpg);
        
        //frame.pack();
        //frame.setResizable(false); //we shouldn't allow resize manually
        //frame.setLocationRelativeTo(null); //center the frame on the user's screen
        //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Editor.game.addKeyListener(listener);
        //frame.setVisible(true);
        
        rpg.start();*/
        //rpg = new RPG(file1);

        //JPanel panel = new JPanel();

        //panel = new JPanel();
        //panel.setLayout(new GridLayout());


        //panel.getContentPane().add(rpg);

        //panel.pack();
        //panel.setResizable(false); //we shouldn't allow resize manually
        //panel.setLocationRelativeTo(null); //center the frame on the user's screen
        //panel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //panel.add(this);
        panel.addKeyListener(listener);
        panel.setVisible(true);

        //rpg = new RPG(file1);
        rpg.start();

        //original

        //rpg = new RPG(file1);

        /*JFrame frame = new JFrame("Rothens RPG " + version);
        frame.setLayout(new GridLayout());
        
        frame.getContentPane().add(rpg);
        
        frame.pack();
        frame.setResizable(false); //we shouldn't allow resize manually
        frame.setLocationRelativeTo(null); //center the frame on the user's screen
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(listener);
        frame.setVisible(true);*/

        //rpg = new RPG(file1);
        //rpg.start();


    }

    public synchronized void start() {
        if (running) {
            return;
        }
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public synchronized void stop() {
        if (!running) {
            return;
        }
        running = false;
        try {
            thread.join();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public void run() {

        double upSec = 0;
        long lastTime = System.nanoTime();
        double secPerTick = 1 / 60.0; //60 FPS
        int cnt = 0;
        int frames = 0;

        while (running) {

            //FPS limit woohoo :D
            long now = System.nanoTime();
            long passed = now - lastTime;
            lastTime = now;

            if (passed < 0) {
                passed = 0;
            }

            if (passed > 100000000) {
                passed = 100000000;
            }

            upSec += passed / 1000000000.0;

            boolean ticked = false;

            while (upSec > secPerTick) {
                tick();
                upSec -= secPerTick;
                ticked = true;
                cnt++;
                if (cnt % 60 == 0) {
                    FPS = frames;
                    lastTime += 1000;
                    frames = 0;
                }
            }
            if (ticked) {
                render();
                frames++;
            }
        }

    }

    private void tick() {
        game.tick();
    }

    private void render() {
        BufferStrategy bfs = this.getBufferStrategy();
        if (bfs == null) {
            createBufferStrategy(2);
            return;
        }
        screen.render(game);
        System.arraycopy(screen.pixels, 0, pixels, 0, WIDTH * HEIGHT);
        Graphics g = bfs.getDrawGraphics();
        //clear the screen
        g.setColor(Color.black);

        g.fillRect(0, 0, 640, 480);

        g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
        g.setColor(Color.red);
        g.drawString(FPS + " FPS", 10, 10);
        g.drawString("tX: " + game.player.getLocation().getTileX() + " tY: " + game.player.getLocation().getTileY(), 10, 20);
        g.dispose();
        bfs.show();



    }
}
